import SockJS from 'sockjs-client/dist/sockjs.min'
import store from '../store/index.js'

export class ChatSocket {
    constructor(endpoint) {
        // 动态构建带鉴权参数的连接地址
        this.messageBuffer = new Map() // 消息分片缓冲区
        this.url = this.buildAuthedUrl(endpoint)
        this.socket = null
        this.reconnectAttempts = 0
        this.maxReconnectAttempts = 5
        this.heartbeatTimer = null
        this.lastActivityTime = Date.now()
        this.statusListeners = {
            open: [],
            close: [],
            error: []
        }
    }

    // 构造带鉴权参数的URL
    buildAuthedUrl(endpoint) {
        const token = store.getters.authToken
        const separator = endpoint.includes('?') ? '&' : '?'
        return `${endpoint}${separator}satoken=${encodeURIComponent(token)}`
    }

    connect(messageHandler) {
        this.cleanup()
        this.messageHandler = messageHandler

        this.socket = new SockJS(this.url, null, {
            transports: ['websocket', 'xhr-streaming', 'xhr-polling']
        })

        this.bindSocketEvents()
    }

    bindSocketEvents() {
        this.socket.onopen = () => {
            this.reconnectAttempts = 0
            this.startHeartbeatMonitor()
            this.notifyStatus('open')
        }

        this.socket.onmessage = (e) => {
            this.handleIncomingMessage(e)
        }

        this.socket.onerror = (e) => {
            console.error('WS Error:', e)
            this.handleConnectionError()
        }

        this.socket.onclose = (e) => {
            console.log('WS Closed:', e)
            this.notifyStatus('close')
            this.scheduleReconnect()
        }
    }

    // 修改消息处理方法
    handleIncomingMessage(e) {
        this.lastActivityTime = Date.now()
        try {
            const chunk = JSON.parse(e.data)
            // 心跳处理
            if (chunk === 'PING') {
                this.sendHeartbeat()
                return
            }
            if (chunk === 'SESSION_EXPIRED') {
                this.handleSessionExpired()
                return
            }

            // 分片消息处理
            if (chunk.messageId && Number.isInteger(chunk.chunkIndex)) {
                this.processChunk(chunk)
            } else {
                this.messageHandler?.(e.data) // 兼容普通消息
            }
        } catch (error) {
            console.error('消息解析失败:', error)
        }
    }

    sendHeartbeat() {
        if (this.isConnected) {
            this.socket.send('PONG')
        }
    }

    startHeartbeatMonitor() {
        clearInterval(this.heartbeatTimer)
        this.heartbeatTimer = setInterval(() => {
            if (!this.isConnected) return

            const inactiveDuration = Date.now() - this.lastActivityTime
            if (inactiveDuration > 60000) {
                console.warn('心跳超时，触发重连')
                this.scheduleReconnect()
            }
        }, 30000)
    }

    scheduleReconnect() {
        if (this.reconnectAttempts < this.maxReconnectAttempts) {
            this.reconnectAttempts++
            setTimeout(() => {
                this.connect(this.messageHandler)
            }, Math.min(3000 * this.reconnectAttempts, 15000))
        }
    }

    handleConnectionError() {
        if (this.reconnectAttempts === 0) {
            this.notifyStatus('error', '连接异常，正在尝试重连...')
        }
        this.scheduleReconnect()
    }

    handleSessionExpired() {
        store.dispatch('logout')
        this.notifyStatus('error', '会话已过期，请重新登录')
        setTimeout(() => window.location.reload(), 1500)
    }

    // 新增分片处理逻辑
    processChunk(chunk) {
        const bufferKey = `${chunk.messageId}_${chunk.type || 'default'}`

        if (!this.messageBuffer.has(bufferKey)) {
            this.messageBuffer.set(bufferKey, {
                chunks: new Map(),
                totalChunks: -1,
                receivedCount: 0
            })
        }

        const buffer = this.messageBuffer.get(bufferKey)
        buffer.chunks.set(chunk.chunkIndex, chunk.content)
        buffer.receivedCount++

        // 检测是否接收完成
        if (chunk.isLastChunk || buffer.receivedCount === chunk.totalChunks) {
            const sortedChunks = Array.from(buffer.chunks.entries())
                .sort((a, b) => a - b)
                .map(entry => entry)

            const fullContent = sortedChunks.join('')
            this.messageHandler?.(JSON.stringify({
                id: chunk.messageId,
                content: fullContent,
                isFinal: true
            }))

            this.messageBuffer.delete(bufferKey)
        }
    }

    // 状态管理方法
    on(event, callback) {
        this.statusListeners[event]?.push(callback)
    }

    notifyStatus(event, ...args) {
        this.statusListeners[event]?.forEach(cb => cb(...args))
    }

    get isConnected() {
        return this.socket?.readyState === SockJS.OPEN
    }

    send(message) {
        if (this.isConnected) {
            this.socket.send(JSON.stringify(message))
        }
    }

    cleanup() {
        clearInterval(this.heartbeatTimer)
        if (this.socket) {
            this.socket.close()
            this.socket = null
        }
    }
}